package org.ytor.core.sqlflow.builder.support;

import org.ytor.common.util.Strs;
import org.ytor.core.sqlflow.builder.AbsBuilder;
import org.ytor.core.sqlflow.builder.IOrderedParams;
import org.ytor.core.sqlflow.builder.select.ISelect;

import java.util.ArrayList;
import java.util.List;

/**
 * created by yangtong on 2025/8/7 22:20:42
 * <br/>
 * join 构造
 */
public class JoinBuilder extends AbsBuilder implements IOrderedParams {
    public enum JoinType {INNER, LEFT, RIGHT}

    /**
     * 连接类型
     */
    private final JoinType type;

    /**
     * 连接对象
     */
    private Class<?> joinClass;

    /**
     * 连接对象（子查询）
     */
    private ISelect joinSubClass;

    /**
     * 别名
     */
    private final String alias;
    /**
     * 连接条件
     */
    private final String onClause;

    /**
     * on 子句参数
     */
    private final List<Object> onParams;

    public JoinBuilder(JoinType type, Class<?> joinClass, String alias, String onClause, List<Object> onParams) {
        this.type = type;
        this.joinClass = joinClass;
        this.alias = alias;
        this.onClause = onClause;
        this.onParams = onParams == null ? List.of() : onParams;
    }

    public JoinBuilder(JoinType type, ISelect joinSubClass, String alias, String onClause, List<Object> onParams) {
        this.type = type;
        this.joinSubClass = joinSubClass;
        this.alias = alias;
        this.onClause = onClause;
        this.onParams = onParams == null ? List.of() : onParams;
    }

    @Override
    public String toSql() {
        String joinTypeSql = switch (type) {
            case INNER -> "INNER JOIN";
            case LEFT -> "LEFT JOIN";
            case RIGHT -> "RIGHT JOIN";
        };
        // 普通表连接
        if (joinClass != null) {
            return joinTypeSql + "\n\t" + getTableName(joinClass) + " " + alias + onClause;
        }
        // 虚拟表连接
        else {
            String subSelectSql = joinSubClass.toSql();
            subSelectSql = subSelectSql.replaceAll("\n", " ")
                    .replaceAll("\t", " ")
                    .replaceAll("\\s+", " ")
                    .trim();
            return Strs.format("{}\n\t({}) {}{}", joinTypeSql, subSelectSql, alias, onClause);
        }
    }

    @Override
    public List<Object> orderedParams() {
        List<Object> all = new ArrayList<>();
        if (joinSubClass != null) {
            all.addAll(joinSubClass.orderedParams()); // 子查询参数先出现
        }
        if (onParams != null && !onParams.isEmpty()) {
            all.addAll(onParams);
        }
        return all;
    }
}

